package cn.jbolt.core.db.datasource;

import cn.hutool.core.util.StrUtil;
import cn.jbolt.core.db.dialect.JBoltDMDialect;
import cn.jbolt.core.db.dialect.JBoltMysqlDialect;
import cn.jbolt.core.db.dialect.JBoltOracleDialect;
import cn.jbolt.core.db.dialect.JBoltPostgresqlDialect;
import cn.jbolt.core.db.sql.DBType;
import cn.jbolt.core.gen.JBoltMetaBuilder;
import cn.jbolt.core.gen._JBoltOracleMetaBuilder;
import cn.jbolt.core.gen._JBoltSqlServerMetaBuilder;
import cn.jbolt.core.service.base.JBoltCommonService;
import com.jfinal.kit.StrKit;
import com.jfinal.log.Log;
import com.jfinal.plugin.activerecord.Config;
import com.jfinal.plugin.activerecord.DbKit;
import com.jfinal.plugin.activerecord.dialect.SqlServerDialect;
import com.jfinal.plugin.activerecord.generator.TableMeta;

import javax.sql.DataSource;
import java.util.List;
import java.util.function.Predicate;

public class JBoltTableMetaUtil {
	protected static final Log LOG = Log.getLog(JBoltCommonService.class);
	/**
	 * 获取指定数据源下指定数据表的表结构
	 * @param datasourceConfigName 数据源配置名
	 * @param dbType
	 * @param tableName
	 * @param isView
	 * @return
	 */
	public static TableMeta getTableMeta(String datasourceConfigName,String dbType,String tableName,boolean isView) {
		JBoltMetaBuilder metaBuilder = null;
		Config config = DbKit.getConfig(datasourceConfigName);
		if(config==null) {
			throw new RuntimeException("数据源配置【"+datasourceConfigName+"】无效");
		}
		DataSource dataSource = config.getDataSource();
		if(dataSource == null) {
			throw new RuntimeException("数据源配置【"+datasourceConfigName+"】DataSource为null");
		}
		//设置schema
		JBoltDatasource jBoltDatasource = JBoltDataSourceUtil.me.getJBoltDatasource(datasourceConfigName);
		if(jBoltDatasource == null){
			throw new RuntimeException("数据源配置【"+datasourceConfigName+"】加载异常 无法获取jboltDataSource");
		}
		String dbSchema=jBoltDatasource.getDbSchema();
		switch (dbType) {
		case DBType.MYSQL:
			metaBuilder = new JBoltMetaBuilder(dataSource);
			metaBuilder.setDialect(new JBoltMysqlDialect());
			if(StrKit.notBlank(dbSchema)) {
				metaBuilder.setSchemaPattern(dbSchema);
			}
			break;
		case DBType.ORACLE:
			metaBuilder = new _JBoltOracleMetaBuilder(dataSource);
			metaBuilder.setDialect(new JBoltOracleDialect());
			if(StrKit.notBlank(dbSchema)) {
				metaBuilder.setSchemaPattern(dbSchema);
			}
			break;
		case DBType.SQLSERVER:
			metaBuilder = new _JBoltSqlServerMetaBuilder(dataSource);
			metaBuilder.setDialect(new SqlServerDialect());
			if(StrKit.notBlank(dbSchema)) {
				metaBuilder.setSchemaPattern(dbSchema);
			}
			break;
		case DBType.POSTGRESQL:
			metaBuilder = new JBoltMetaBuilder(dataSource);
			metaBuilder.setDialect(new JBoltPostgresqlDialect());
			String schemaPattern=getPostGresqlSchema(jBoltDatasource.getJdbcUrl());
			if(StrKit.notBlank(schemaPattern)){
				metaBuilder.setSchemaPattern(schemaPattern);
			}else if(StrKit.notBlank(dbSchema)) {
				metaBuilder.setSchemaPattern(dbSchema);
			}
			break;
		case DBType.DM:
			metaBuilder = new JBoltMetaBuilder(dataSource);
			metaBuilder.setDialect(new JBoltDMDialect());
			if(StrKit.notBlank(dbSchema)) {
				metaBuilder.setSchemaPattern(dbSchema);
			}
			break;
		}
		if(metaBuilder==null) {
			throw new RuntimeException("目前只支持Mysql、Oracle、SqlServer、Postgresql、达梦 5个数据库");
		}

		metaBuilder.setGenerateRemarks(true);
		metaBuilder.setGenerateView(isView);
		metaBuilder.skip(new Predicate<String>() {
			@Override
			public boolean test(String t) {
				return !t.equals(tableName);
			}
		});
		List<TableMeta> tableMetas = metaBuilder.build();
		if(tableMetas==null || tableMetas.size()==0) {
			throw new RuntimeException("数据源配置【"+datasourceConfigName+"】下表【"+tableName+"】未获取到表和字段信息");
		}
		return tableMetas.get(0);
	}

	private static String getPostGresqlSchema(String jdbcUrl) {
		if(jdbcUrl.indexOf("currentSchema")!=-1) {
			String schemaname=jdbcUrl.substring(jdbcUrl.lastIndexOf("currentSchema")+13).replace("=", "").trim();
			if(StrUtil.isNotBlank(schemaname)) {
				return schemaname;
			}
		}
		return null;
	}
}
